package com.bdd.jpa.factory;

import com.bdd.jpa.entity.domain.ScheduleJob;
import com.bdd.jpa.service.op.SmsService;
import com.bdd.jpa.service.schedule.JobService;
import com.bdd.jpa.util.ParamsUtil;
import com.bdd.jpa.util.SpringUtil;
import com.bdd.jpa.util.entity.ParamsObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.sun.org.apache.regexp.internal.RE;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.swing.event.ListSelectionEvent;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author Bdd
 * @Description 任务具体逻辑
 * @Date 2019/9/20 17:11
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class QuartzFactory implements Job {

    @Autowired
    private JobService jobService;


    /**
     * 调用具体的方法
     * 未更改任务调用结束后，消息状态
     *
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        System.out.println("执行任务");
        //获取调度数据
        ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
        //获取对应的Bean
        Object object = SpringUtil.getBean(scheduleJob.getClassName());

        try {
            //获取方法中的参数
            List<ParamsObject> list = ParamsUtil.JSONtoParamsObject(scheduleJob.getParams());
            Class<?> classes[] = (Class<?>[]) getParamsClass(list);
            Object objects[] = getParamsValue(list);
            Method method = object.getClass().getMethod(scheduleJob.getMethodName(), classes);
            method.invoke(object, objects);
            //利用反射执行对应方法
            jobService.deleteJob(scheduleJob);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Class[] getParamsClass(List<ParamsObject> list) throws ClassNotFoundException {
//        if(list == null || list.isEmpty())
//            return null;
//        Class<?> classes[] = new Class[list.size()];
//        int index = 0;
//        for (ParamsObject paramsObject : list){
//            classes[index++] = Class.forName(paramsObject.getName());
//        }
//        return classes;
        Class[] objects = (Class[]) list.stream().map(item -> {
            try {
                Class clazz = Class.forName(item.getName());
                return clazz;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }).toArray(Class[]::new);
        return objects;
    }

    private Object[] getParamsValue(List<ParamsObject> list) {
        if(list == null || list.isEmpty())
            return null;

        return list.stream().parallel().
                map(ParamsObject::getValue).toArray();

    }


    /**
     * 构建方法参数
     *
     * @param params
     * @return
     * @throws ClassNotFoundException
     */
    private Class<?>[] getClassArray(String params) throws ClassNotFoundException {
        String temp[] = params.split(",");
        Class<?> result[] = new Class<?>[temp.length];
        int index = 0;
        for (String item : temp) {
            result[index++] = Class.forName(item);
        }
        return result;
    }


    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, IOException {

//        QuartzFactory quartzFactory = new QuartzFactory();
//        Class<?> clazz[] = quartzFactory.getClassArray("java.lang.String");
//        Object o = SmsService.class.newInstance();
//        Method method = SmsService.class.getMethod("sendMessage", clazz);
//        method.invoke(o, "1412");
        List<ParamsObject> list = new ArrayList<>();
        ParamsObject paramsObject =  new ParamsObject("java.lang.String","name");
        System.out.println(paramsObject);
        list.add(paramsObject);

        String json = ParamsUtil.paramsListToJSON(list);
        System.out.println(json);
        list = ParamsUtil.JSONtoParamsObject(json);
        list.forEach(System.out::println);
//        Class clazz = Class.forName(list.get(0).getName());
    }

}